/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2019 HUST Dian Group
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Original Author: Pengyu Liu <eicliupengyu@gmail.com>
 */
#pragma once
#include "ns3/object.h"
#include "robo-geometry.h"
#include "robo-mobility.h"
namespace ns3 {
enum CollisionType {
  Collision_Type_Circle,
  Collision_Type_Polygon,
  Collision_Type_Boundary,
};
class RoboMobility;
class RoboActor : public Object
{
  friend class RoboTeamHelper;
  friend class RoboJudge;
  friend class RoboBase;
  friend class RoboMobility;
  friend class VariableSpeedMobility;
  friend class FunctionMobility;
  friend class ConstLocationMobility;

public:
  RoboActor (void);
  ~RoboActor (void);
  static TypeId GetTypeId (void);
  virtual TypeId GetInstanceTypeId (void) const;
  virtual void DoDispose (void);

  typedef Callback<void, Ptr<RoboActor>> CollisionCallback;
  typedef Callback<void, FILE *> PlotCallback;
  typedef Callback<void, float> UpdateCallback;
  CollisionType GetCollisionType (void) const;
  FVector GetGlobalLocation (void) const;
  FAngle GetGlobalRotation (void) const;
  uint32_t GetCollisionMask (void) const;
  uint32_t GetSelfMask (void) const;
  float GetRedius (void) const;
  Ptr<RoboMobility> GetMobility ();

  friend bool IsCollision (Ptr<RoboActor> obj1, Ptr<RoboActor> obj2);
  friend bool IsPolygonPolygonCollision (Ptr<RoboActor> obj1, Ptr<RoboActor> obj2);
  friend bool IsCirclePolygonCollision (Ptr<RoboActor> obj1, Ptr<RoboActor> obj2);
  friend bool IsObjectBoundaryCollision (Ptr<RoboActor> obj1, Ptr<RoboActor> obj2);

  uint32_t AddCollisionCallback (CollisionCallback cb);
  uint32_t AddUpdateCallback (UpdateCallback cb);

protected:
  Ptr<RoboMobility> m_mobility;
  CollisionType m_collisionType{Collision_Type_Circle};
  FVector m_globalLocation;
  FAngle m_globalRotation;
  float m_redius{0};
  std::vector<FVector> m_boundaryPoint;
  uint32_t m_collisionMask;
  uint32_t m_selfMask;

  void SetCollisionType (CollisionType type);
  void SetGlobalLocation (FVector globallocation);
  void SetGlobalRotation (FAngle globalrotation);
  void SetCollisionMask (uint32_t collisionMask);
  void SetSelfMask (uint32_t selfMask);
  void SetRedius (float redius);
  void AddBoundaryPoint (FVector boundaryPoint);
  void AddBoundaryPoint (std::vector<FVector> boundaryPoints);

  std::vector<CollisionCallback> m_collisionCallbackList;
  std::vector<UpdateCallback> m_updateCallbackList;
  PlotCallback m_initPlot;
  PlotCallback m_updatePlot;

  bool m_isDeleted{false}; //从场景中删除
  bool m_isDestroy{false}; //禁用射击，移动等

  void IndicateCollision (Ptr<RoboActor> oth);
  void Update (float delta);
  void SetMobility (Ptr<RoboMobility> mob);
};

} // namespace ns3
